import axios, { type AxiosError, type AxiosInstance, type InternalAxiosRequestConfig, type AxiosResponse } from 'axios'
import { ElMessage } from 'element-plus'
import { useAuthStore } from '@/stores/authStore'
import type { ApiResponse } from '@/types/request'

const WHITE_LIST = ['/login']

const service: AxiosInstance = axios.create({
  baseURL: import.meta.env['VITE_API_URL'],
  timeout: 10000,
  withCredentials: true,
})

let isRefreshing = false
let requestsQueue: Array<(token: string) => void> = []

// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const authStore = useAuthStore()
    const token = authStore.token

    if (token && !WHITE_LIST.some(path => config.url?.startsWith(path))) {
      config.headers = config.headers || {}
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  (error: AxiosError) => {
    ElMessage.error('请求配置错误')
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  <T>(response: AxiosResponse<ApiResponse<T>>) => {
    const res = response.data
    if (res.code !== 200) {
      ElMessage.error(res.message || '请求失败')
      return Promise.reject(new Error(res.message || '请求失败'))
    }
    return res.data
  },
  async (error: AxiosError) => {
    const authStore = useAuthStore()

    if (error.response?.status === 401) {
      const refreshToken = authStore.getRefreshToken()
      const originalRequest = error.config!

      if (refreshToken) {
        if (!isRefreshing) {
          isRefreshing = true
          try {
            const res = await service.post<ApiResponse<{ token: string }>>('/auth/refresh', { refreshToken })
            const newToken = res.data.data.token
            authStore.setToken(newToken)

            requestsQueue.forEach(cb => cb(newToken))
            requestsQueue = []

            return service(originalRequest)
          } catch (refreshError) {
            authStore.clearToken()
            window.location.href = '/login'
            return Promise.reject(refreshError)
          } finally {
            isRefreshing = false
          }
        } else {
          return new Promise<AxiosResponse>((resolve) => {
            requestsQueue.push((token: string) => {
              if (originalRequest.headers) {
                originalRequest.headers.Authorization = `Bearer ${token}`
              }
              resolve(service(originalRequest))
            })
          })
        }
      } else {
        authStore.clearToken()
        window.location.href = '/login'
      }
    }

    let message = '请求错误'
    if (error.response) {
      const status = error.response.status
      switch (status) {
        case 400: message = '请求参数错误'; break
        case 401: message = '未授权，请登录'; break
        case 403: message = '没有权限'; break
        case 404: message = '请求地址不存在'; break
        case 500: message = '服务器错误'; break
        default: message = `连接错误(${status})`
      }
    } else if (error.message.includes('timeout')) {
      message = '请求超时，请稍后重试'
    } else if (error.message.includes('Network Error')) {
      message = '网络错误，请检查网络连接'
    }

    ElMessage.error(message)
    return Promise.reject(error)
  }
)

export const http = {
  get<T = unknown>(url: string, params?: object) {
    return service.get<T>(url, { params })
  },
  post<T = unknown>(url: string, data?: object) {
    return service.post<T>(url, data)
  },
  put<T = unknown>(url: string, data?: object) {
    return service.put<T>(url, data)
  },
  delete<T = unknown>(url: string, params?: object) {
    return service.delete<T>(url, { params })
  }
}

export default service
